/**
 * @File name: init.c
 * @Synopsis:
 * @Author: xing.dai@aliyun.com
 * @Version: 0.0.1
 * @Date: 2018-12-24 20:44
 */

#include "init.h"
#include "stdio.h"

#ifdef __GNUC__
extern struct _config_init __hw_init_array_0_start;
extern struct _config_init __hw_init_array_0_end;
extern struct _config_init __hw_init_array_1_start;
extern struct _config_init __hw_init_array_1_end;
extern struct _config_init __hw_init_array_2_start;
extern struct _config_init __hw_init_array_2_end;
extern struct _config_init __hw_init_array_3_start;
extern struct _config_init __hw_init_array_3_end;
extern struct _config_init __hw_init_array_end;
extern struct _config_init __sw_init_array_0_start;
extern struct _config_init __sw_init_array_0_end;
extern struct _config_init __sw_init_array_1_start;
extern struct _config_init __sw_init_array_1_end;
extern struct _config_init __sw_init_array_2_start;
extern struct _config_init __sw_init_array_2_end;
extern struct _config_init __sw_init_array_3_start;
extern struct _config_init __sw_init_array_3_end;
extern struct _config_init __sw_init_array_end;
#else   /* ARMCC */
extern struct _config_init Image$$__hw_init_array_0$$Base;
extern struct _config_init Image$$__hw_init_array_1$$Base;
extern struct _config_init Image$$__hw_init_array_2$$Base;
extern struct _config_init Image$$__hw_init_array_3$$Base;
extern struct _config_init Image$$__hw_init_array_3$$Limit;
extern struct _config_init Image$$__sw_init_array_0$$Base;
extern struct _config_init Image$$__sw_init_array_1$$Base;
extern struct _config_init Image$$__sw_init_array_2$$Base;
extern struct _config_init Image$$__sw_init_array_3$$Base;
extern struct _config_init Image$$__sw_init_array_3$$Limit;
#endif

static struct _config_init *hw_init_levels[] = {
#ifdef __GNUC__
    &__hw_init_array_0_start,
    &__hw_init_array_1_start,
    &__hw_init_array_2_start,
    &__hw_init_array_3_start,
    /* End marker */
    &__hw_init_array_end,
#else   /* ARMCC */
    &Image$$__hw_init_array_0$$Base,
    &Image$$__hw_init_array_1$$Base,
    &Image$$__hw_init_array_2$$Base,
    &Image$$__hw_init_array_3$$Base,
    /* End marker */
    &Image$$__hw_init_array_3$$Limit,
#endif
};

static struct _config_init *sw_init_levels[] = {
#ifdef __GNUC__
    &__sw_init_array_0_start,
    &__sw_init_array_1_start,
    &__sw_init_array_2_start,
    &__sw_init_array_3_start,
    /* End marker */
    &__sw_init_array_end,
#else   /* ARMCC */
    &Image$$__sw_init_array_0$$Base,
    &Image$$__sw_init_array_1$$Base,
    &Image$$__sw_init_array_2$$Base,
    &Image$$__sw_init_array_3$$Base,
    /* End marker */
    &Image$$__sw_init_array_3$$Limit,
#endif
};

void hw_do_init(int level)
{
    struct _config_init *info;

    for (info = hw_init_levels[level]; info < hw_init_levels[level + 1]; info++) {
        info->init(info);
    }
}

void sw_do_init(int level)
{
    struct _config_init *info;

    for (info = sw_init_levels[level]; info < sw_init_levels[level + 1]; info++) {
        info->init(info);
    }
}

#if 0
int a_init(struct _config_init *info)
{
    printf("%s exec.\n", __func__);
    return 0;
}
CONFIG_HW_INIT(aaa, a_init, NULL, HW_INIT_EARLY_LEVEL);

int b_init(struct _config_init *info)
{
    printf("%s exec.\n", __func__);


    return 0;
}
CONFIG_HW_INIT(bbb, b_init, NULL, HW_INIT_LEVEL);


int c_init(struct _config_init *info)
{
    printf("%s exec.\n", __func__);

    return 0;
}
CONFIG_SW_INIT(ccc, c_init, NULL, SW_INIT_EARLY_LEVEL);


int d_init(struct _config_init *info)
{
    printf("%s exec.\n", __func__);

    return 0;
}
CONFIG_SW_INIT(ddd, d_init, NULL, SW_INIT_LEVEL);
#endif

